class Solution {
public:
/*
如果数组是有序的，那么大家都会想到并使用二分搜索，但本题设置了这样一个障碍：数组是rotate过的。这样，原先有序的数组就变成了局部有序：（假设）分为两个有序的子数组，并且左边子数组中的元素都大于右边子数组中的元素。这时，采用二分搜索，需要判断数组nums[left..right]和下标mid分别处于什么位置。分为以下2种情况：
1.nums[mid] >= nums[left]
这时可判断下标left和mid处于同一个子数组的下标范围中，至于right，未知。我们现在要确定，是到左半边数组即nums[left..mid-1]中继续搜索，还是到右半边数组nums[mid+1..right]中搜索。
到右半边数组搜索有两种情况，一是target>nums[mid]，这个很自然，依据是二分搜索的基本原理；二是target<nums[left]，这说明target不在整个原数组即nums[0..nums.size()-1] rotate后的左半边有序数组里，而在右边的有序子数组里。这两种情况只要满足其中一种，就到nums[mid+1..right]中继续搜索，而不用管nums[left..mid-1]，因此令left = mid+1；
2.nums[mid] < nums[left]
这时可判断下标left在左半边有序数组中，mid在右半边有序数组中。此时若要到nums[mid+1..right]中搜索，需同时满足两个条件：①target>nums[mid]，这个也很自然，无须解释，但要注意，别忘了第二个条件：②target<=nums[right],否则target就不在这部分的有序子数组中了，必须到左半边有序数组中搜索（在常规的二分搜索中若target>nums[right]即可判定无解，搜索失败，而在本题条件下，target可能存在于被rotate到数组前半部分的子数组中，还须进一步搜索）。
综上，在(nums[mid]>=nums[left] && (target>nums[mid] || target<nums[left])) || (nums[mid]<nums[left] && target>nums[mid] && target<=nums[right])为真时令left = mid+1，到nums[mid..right]中搜索，否则令right = mid-1，到nums[left..mid-1]中寻找。
*/
    int search(vector<int>& nums, int target) {
        if(nums.size() == 0)
            return -1;
        int left = 0;
        int right = nums.size()-1;
        while(left <= right){
            int mid = (left+right)/2;
            if(target == nums[mid])
                return mid;
            if((nums[mid]>=nums[left] && (target>nums[mid] || target<nums[left])) || (nums[mid]<nums[left] && target>nums[mid] && target<=nums[right]))
                left = mid + 1;
            else
                right = mid -1;
        }
        return -1;
    }
};